<?php
declare (strict_types=1);

namespace app\admin\controller;

use app\common\model\Level;
use think\App;
use think\exception\ValidateException;
use think\facade\View;
use think\response\Json;
use app\common\facade\Builder;
use app\common\model\Assets;
use app\common\model\Logs;

class User extends Base
{
    //主键，默认为id
    protected string $pk = 'id';

    //主模型
    protected string $model = '\app\common\model\User';

    //验证器
    protected string $validate = 'User';

    //关联模型
    protected array $hasOne = ['level', 'assets'];

    protected array $append = ['parent_info'];

    //自定义方法排序
    protected array $sort = [
        'ordinary' => [
            'create_time' => 'desc'
        ],
        'formal'   => [
            'active_time' => 'desc'
        ]
    ];

    //普通会员
    public function ordinary(): string
    {
        return $this->setTable(['add'], [
            'login' => ['title' => '登录', 'url' => url('user/login')->build(), 'event' => '_submit'],
            'edit',
            'delete'
        ], [['is_active', '=', 1]]);
    }

    //正式会员
    public function formal(): string
    {
        return $this->setTable([], [
            'login' => ['title' => '登录', 'url' => url('user/login')->build(), 'event' => '_submit'],
            'edit'
        ], [['is_active', '=', 2]], 2, 150);
    }

    public function setTable($tb = [], $rb = [], $extra_map = [], $type = 1, $width = 200): string
    {
        //构建表格数据
        $table = Builder::Table()->addColumn(['type' => 'checkbox', 'title' => '全选', 'fixed' => 'left'])
            ->addColumn(['field' => 'id', 'sort' => true, 'title' => 'ID', 'width' => 80, 'fixed' => 'left'])
            ->addColumn(['field' => 'code', 'title' => '会员编号', 'fixed' => 'left'])
            ->addColumn(['field' => 'nickname', 'title' => '会员昵称', 'modify' => '2,input', 'fixed' => 'left'])
            ->addColumn(['field' => 'mobile', 'title' => '手机号', 'modify' => '2,input', 'fixed' => 'left'])
            ->addColumn(['field' => 'parent_code', 'title' => '邀请码', 'modify' => '1,input', 'hide' => true])
            ->addColumn(['field' => 'parent_info', 'title' => '推荐人']);
        if ($type == 1) {
            $table->addColumn(['field' => 'level_id', 'title' => '会员等级', 'templet' => '<span>{{d.level?d.level.title:"无"}}</span>']);
        } else {
            $table->addColumn(['field' => 'level_id', 'title' => '会员等级', 'modify' => '3,select,getLevel', 'templet' => '<span>{{d.level?d.level.title:"无"}}</span>']);
        }
        //渲染账户
        foreach (Assets::getFields(3) as $k => $v) {
            $table->addColumn(['field' => $k, 'title' => $v, 'templet' => '<span>{{d.assets.' . $k . '}}</span>']);
        }
        return $table->addColumn(['field' => 'my_total', 'title' => '个人业绩'])
            ->addColumn(['field' => 'team_total', 'title' => '团队业绩'])
            ->addColumn(['field' => 'sign_day', 'title' => '累计签到天数'])
            ->addColumn(['field' => 'always_day', 'title' => '连续签到天数'])
            ->addColumn(['field' => 'active_time', 'title' => '激活时间'])
            ->addColumn(['field' => 'create_time', 'title' => '注册时间'])
            ->addColumn(['field' => 'is_lock', 'title' => '是否锁定', 'modify' => '3,radio,getLock', 'templet' => '#is_lock', 'width' => 120])
            ->addColumn(['fixed' => 'right', 'align' => 'center', 'toolbar' => '#barDemo', 'title' => '操作', 'width' => $width])
            ->addTopButtons(array_merge($tb, [
                'reset_1' => [
                    'title' => '重置登录密码',
                    'icon' => 'layui-icon-password',
                    'url' => url('user/reset', ['type' => 1])->build(),
                    'event' => '_batchSubmit'
                ],
                'reset_2' => [
                    'title' => '重置支付密码',
                    'icon' => 'layui-icon-password',
                    'url' => url('user/reset', ['type' => 2])->build(),
                    'event' => '_batchSubmit'
                ],
                'export'
            ]))
            ->addRightButtons($rb)
            ->addSwitchTool([
                ['name' => 'is_lock', 'pk' => $this->pk, 'text' => '否|是']
            ])
            ->addExtraMap($extra_map)
            ->addSearch([
                ['code__nickname__mobile', '会员编号/昵称/手机号', 'input,Like'],
            ], false)
            ->fetch();
    }

    public static function getLevel(): array
    {
        return Level::where(['is_del' => 0])->column('title', 'id');
    }

    public static function getLock(): array
    {
        return ['正常', '锁定'];
    }

    public function save($param = [], $model = true): Json
    {
        $param = $this->request->post();
        if (empty($param['id'])) {
            $param['password'] = '111111';
            $param['pay_password'] = '222222';
        }

        return parent::save($param, $model); // TODO: Change the autogenerated stub
    }

    public function delete(): Json
    {
        $param = $this->request->post();
        $info = $this->model::where(['id' => $param['id']])->find();
        if ($info->is_active == 2) {
            return json(['code' => -1, 'msg' => '该会员已激活，无法删除']);
        }
        $count = $this->model::where(['parent_id' => $param['id'], 'is_del' => 0])->count();
        if ($count) {
            return json(['code' => -1, 'msg' => '该会员已有下级，无法删除']);
        }

        return parent::delete(); // TODO: Change the autogenerated stub
    }

    public function reset($type): Json
    {
        try {
            $ids = $this->request->post('ids');
            if ($type == 1) {
                $key = 'password';
                $value = md5('111111');
                $name = '登录密码';
            } else {
                $key = 'pay_password';
                $value = md5('222222');
                $name = '支付密码';
            }
            $this->model::update([$key => $value], ['id' => $ids]);
            $msg = '重置了【' . $name . '】会员ID【' . implode(',', $ids) . '】';
            Logs::adds($msg, $this->admin->id, $this->admin->admin_name);
            return json(['code' => 1, 'msg' => '已重置']);

        } catch (\Exception $e) {
            return json(['code' => -1, 'msg' => $e->getMessage()]);
        }

    }

    public function login($id): Json
    {
        try {
            $user = $this->model::find($id);
            if ($user->token) {
                $token = $user->token;
            } else {
                $token = md5(time() . json_encode($user));
                $user->token = $token;
                $user->save();
            }
            cookie('token', $token);
            $description = '登录操作，会员【' . $user->code . '】';
            Logs::adds($description, $this->admin['id'], $this->admin['admin_name']);
            return json(['code' => 2, 'msg' => '登录成功，正在跳转']);
        } catch (\Exception $e) {
            return json(['code' => -1, 'msg' => $e->getMessage()]);
        }
    }

    public function recharge()
    {
        $param = $this->request->param();
        if ($this->request->isAjax()) {
            switch ($param['type']) {
                case "get":
                    $user = $this->model::whereLike('code|mobile|nickname', '%' . $param['val'] . '%')
                        ->where(['is_del' => 0])->field('id,code,nickname,mobile')->select();
                    return json(['code' => 0, 'data' => $user]);
                case "account":
                    $assets = Assets::where(['uid' => $param['id']])->value($param['val']);
                    if ($assets) {
                        return json(['code' => 1, 'msg' => '', 'result' => $assets]);
                    } else {
                        return json(['code' => -1, 'msg' => '加载失败']);
                    }
                case "save":
                    try {
                        $this->validate($param, 'Recharge');
                    } catch (ValidateException $e) {
                        return json(['code' => -1, 'msg' => $e->getError()]);
                    }
                    return $this->model::recharge($param, $this->admin);
                default:
                    return json(['code' => -1, 'msg' => '加载失败']);
            }
        }
        View::assign('assets', Assets::getFields(3));
        return View::fetch();
    }
}